//   Copyright 2012,2013 Vaughn Vernon
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.

package com.saasovation.agilepm.application.team;

import com.saasovation.agilepm.application.ApplicationServiceLifeCycle;
import com.saasovation.agilepm.domain.model.team.ProductOwner;
import com.saasovation.agilepm.domain.model.team.ProductOwnerRepository;
import com.saasovation.agilepm.domain.model.team.TeamMember;
import com.saasovation.agilepm.domain.model.team.TeamMemberRepository;
import com.saasovation.agilepm.domain.model.tenant.TenantId;

/**
 * 团队应用服务
 * @author learn
 */
public class TeamApplicationService {

    /**
     * 产品经理存储库
     */
    private ProductOwnerRepository productOwnerRepository;
    /**
     * 团队成员存储库
     */
    private TeamMemberRepository teamMemberRepository;

    /**
     * 由以下参数构造团队应用服务
     * @param aTeamMemberRepository                 团队成员存储库
     * @param aProductOwnerRepository               产品经理存储库
     */
    public TeamApplicationService(
            TeamMemberRepository aTeamMemberRepository,
            ProductOwnerRepository aProductOwnerRepository) {
        // 调用父类默认构造器
        super();

        this.productOwnerRepository = aProductOwnerRepository;
        this.teamMemberRepository = aTeamMemberRepository;
    }

    /**
     * 启用产品经理
     * @param aCommand  产品经理命令
     */
    public void enableProductOwner(EnableProductOwnerCommand aCommand) {
        // 建立租户ID
        TenantId tenantId = new TenantId(aCommand.getTenantId());

        // 应用服务生命周期.开始
        ApplicationServiceLifeCycle.begin();

        try {
            // 由产品经理存储库，建立产品经理
            ProductOwner productOwner =
                    this.productOwnerRepository.productOwnerOfIdentity(
                            tenantId,
                            aCommand.getUsername());

            // 如果产品经理有效的情况下；使用发生日期，启用产品经理
            if (productOwner != null) {
                productOwner.enable(aCommand.getOccurredOn());
            } else {
                // 由命令建立产品经理
                productOwner =
                        new ProductOwner(
                                tenantId,
                                aCommand.getUsername(),
                                aCommand.getFirstName(),
                                aCommand.getLastName(),
                                aCommand.getEmailAddress(),
                                aCommand.getOccurredOn());
                // 保存产品经理
                this.productOwnerRepository().save(productOwner);
                // 应用服务生命周期的成功处理
                ApplicationServiceLifeCycle.success();
            }
        } catch (RuntimeException e) {
            // 应用服务生命周期的失败处理
            ApplicationServiceLifeCycle.fail(e);
        }
    }

    /**
     * 启用团队成员
     * @param aCommand      启用团队成员命令
     */
    public void enableTeamMember(EnableTeamMemberCommand aCommand) {
        // 建立租户ID
        TenantId tenantId = new TenantId(aCommand.getTenantId());
        // 应用服务生命周期.开始
        ApplicationServiceLifeCycle.begin();

        try {
            // 由团队成员存储库建立团队成员
            TeamMember teamMember =
                    this.teamMemberRepository.teamMemberOfIdentity(
                            tenantId,
                            aCommand.getUsername());
            // 如果团队成员有效的情况下；使用发生日期，启用团队成员
            if (teamMember != null) {
                teamMember.enable(aCommand.getOccurredOn());
            } else {
                // 无效的情况下，由命令建立团队成员
                teamMember =
                        new TeamMember(
                                tenantId,
                                aCommand.getUsername(),
                                aCommand.getFirstName(),
                                aCommand.getLastName(),
                                aCommand.getEmailAddress(),
                                aCommand.getOccurredOn());

                // 保存团队成员
                this.teamMemberRepository().save(teamMember);
            }
            // 应用服务生命周期的成功处理
            ApplicationServiceLifeCycle.success();

        } catch (RuntimeException e) {
            // 应用服务生命周期的失败处理
            ApplicationServiceLifeCycle.fail(e);
        }
    }

    /**
     * 改变团队成员邮件地址
     * @param aCommand      改变团队成员邮件地址命令
     */
    public void changeTeamMemberEmailAddress(ChangeTeamMemberEmailAddressCommand aCommand) {
        // 建立租户ID
        TenantId tenantId = new TenantId(aCommand.getTenantId());
        // 应用服务生命周期.开始
        ApplicationServiceLifeCycle.begin();

        try {
            // 由存储库建立产品经理
            ProductOwner productOwner =
                    this.productOwnerRepository.productOwnerOfIdentity(
                            tenantId,
                            aCommand.getUsername());
            // 如果产品经理有效的情况下，改变邮件地址并保存
            if (productOwner != null) {
                productOwner
                    .changeEmailAddress(
                        aCommand.getEmailAddress(),
                        aCommand.getOccurredOn());

                this.productOwnerRepository().save(productOwner);
            }
            // 由存储库建立团队成员
            TeamMember teamMember =
                    this.teamMemberRepository.teamMemberOfIdentity(
                            tenantId,
                            aCommand.getUsername());
            // 如果团队成员有效的情况下，改变邮件地址并保存
            if (teamMember != null) {
                teamMember
                    .changeEmailAddress(
                            aCommand.getEmailAddress(),
                            aCommand.getOccurredOn());

                this.teamMemberRepository().save(teamMember);
            }
            // 应用服务生命周期的成功处理
            ApplicationServiceLifeCycle.success();

        } catch (RuntimeException e) {
            // 应用服务生命周期的失败处理
            ApplicationServiceLifeCycle.fail(e);
        }
    }

    /**
     * 改变团队成员名
     * @param aCommand      改变团队成员名命令
     */
    public void changeTeamMemberName(ChangeTeamMemberNameCommand aCommand) {
        // 建立租户ID
        TenantId tenantId = new TenantId(aCommand.getTenantId());
        // 应用服务生命周期.开始
        ApplicationServiceLifeCycle.begin();

        try {
            // 由存储库建立产品经理
            ProductOwner productOwner =
                    this.productOwnerRepository.productOwnerOfIdentity(
                            tenantId,
                            aCommand.getUsername());
            // 如果产品经理有效的情况下，改变名字并保存
            if (productOwner != null) {
                productOwner
                    .changeName(
                            aCommand.getFirstName(),
                            aCommand.getLastName(),
                            aCommand.getOccurredOn());

                this.productOwnerRepository().save(productOwner);
            }
            // 由存储库建立团队成员
            TeamMember teamMember =
                    this.teamMemberRepository.teamMemberOfIdentity(
                            tenantId,
                            aCommand.getUsername());
            // 如果团队成员有效的情况下，改变名字并保存
            if (teamMember != null) {
                teamMember
                    .changeName(
                            aCommand.getFirstName(),
                            aCommand.getLastName(),
                            aCommand.getOccurredOn());

                this.teamMemberRepository().save(teamMember);
            }
            // 应用服务生命周期的成功处理
            ApplicationServiceLifeCycle.success();

        } catch (RuntimeException e) {
            // 应用服务生命周期的失败处理
            ApplicationServiceLifeCycle.fail(e);
        }
    }

    /**
     * 禁用产品经理
     * @param aCommand      禁用产品经理命令
     */
    public void disableProductOwner(DisableProductOwnerCommand aCommand) {
        // 建立租户ID
        TenantId tenantId = new TenantId(aCommand.getTenantId());
        // 应用服务生命周期.开始
        ApplicationServiceLifeCycle.begin();

        try {
            // 由存储库建立产品经理
            ProductOwner productOwner =
                    this.productOwnerRepository.productOwnerOfIdentity(
                            tenantId,
                            aCommand.getUsername());
            // 如果产品经理为有效的情况下，由发生日期禁用产品经理并保存
            if (productOwner != null) {
                productOwner.disable(aCommand.getOccurredOn());

                this.productOwnerRepository().save(productOwner);
            }
            // 应用服务生命周期的成功处理
            ApplicationServiceLifeCycle.success();

        } catch (RuntimeException e) {
            // 应用服务生命周期的失败处理
            ApplicationServiceLifeCycle.fail(e);
        }
    }

    /**
     * 禁用团队成员
     * @param aCommand      禁用团队成员命令
     */
    public void disableTeamMember(DisableTeamMemberCommand aCommand) {
        // 建立租户ID
        TenantId tenantId = new TenantId(aCommand.getTenantId());
        // 应用服务生命周期.开始
        ApplicationServiceLifeCycle.begin();

        try {
            // 由存储库建立团队成员
            TeamMember teamMember =
                    this.teamMemberRepository.teamMemberOfIdentity(
                            tenantId,
                            aCommand.getUsername());
            // 如果团队成员有效的情况下，使用发生日期禁用并保存
            if (teamMember != null) {
                teamMember.disable(aCommand.getOccurredOn());

                this.teamMemberRepository().save(teamMember);
            }
            // 应用服务生命周期的成功处理
            ApplicationServiceLifeCycle.success();

        } catch (RuntimeException e) {
            // 应用服务生命周期的失败处理
            ApplicationServiceLifeCycle.fail(e);
        }
    }

    /**
     * 获取产品经理存储库
     * @return              返回产品经理存储库
     */
    private ProductOwnerRepository productOwnerRepository() {
        return this.productOwnerRepository;
    }

    /**
     * 获取团队成员存储库
     * @return              返回团队成员存储库
     */
    private TeamMemberRepository teamMemberRepository() {
        return this.teamMemberRepository;
    }
}
